package org.jeecg.modules.act.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.util.DateUtils;
import org.jeecg.common.util.RedisUtil;
import org.jeecg.common.util.StringUtils;
import org.jeecg.common.wx.Const;
import org.jeecg.common.wx.DateUtil;
import org.jeecg.common.wx.OrderUtils;
import org.jeecg.common.wx.UuidUtil;
import org.jeecg.modules.act.dto.SignUp;
import org.jeecg.modules.act.dto.Verify;
import org.jeecg.modules.act.entity.*;
import org.jeecg.modules.act.dto.WxAct;
import org.jeecg.modules.act.mapper.*;
import org.jeecg.modules.act.service.*;
import org.jeecg.modules.act.vo.*;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.util.*;

/**
 * @Description: 活动表
 * @Author: jeecg-boot
 * @Date: 2019-09-04
 * @Version: V1.0
 */
@Service
public class ActivityServiceImpl extends ServiceImpl<ActivityMapper, Activity> implements IActivityService {


    @Resource
    private IActMatterService matterService;
    @Resource
    private ActivityMapper activityMapper;
    @Resource
    private ActContentMapper contentMapper;
    @Resource
    private IActMatterValueService valueService;
    @Resource
    private ActUserRecordMapper recordMapper;
    @Resource
    private ActUserMapper userMapper;
    @Resource
    private ActDictMapper dictMapper;
    @Resource
    private ActShareMapper shareMapper;
    @Resource
    private IActPayService payService;
    @Resource
    private IActFormService formService;

    /**
     * @param act
     * @return
     */
    @Override
    @Transactional
    public Result addAct(WxAct act) {
        Result<String> result = new Result<>();
        String actId = UuidUtil.get32UUID();
        Activity activity = new Activity();
        BeanUtils.copyProperties(act, activity);
        activity.setId(actId);
        activity.setCreateTime(new Date());
        activity.setShare(0);
        activity.setCurUser(0);
        activity.setDelFlag(0);
        activity.setPay(new BigDecimal(act.getPay()));
        activity.setVersion(1);
        activity.setStatus(1);
        activity.setLinkPhone(act.getLinkPhone());

        ActContent content = new ActContent();
        content.setDelFlag(0);
        content.setCreateTime(new Date());
        content.setActId(actId);
        content.setContent(act.getContent());

        List<ActDictVo> voList = act.getDictVos();
        if (CollectionUtils.isEmpty(voList)) {
            result.setSuccess(false);
            result.setMessage("请勾选报名要填写的参数");
        } else {
            List<ActMatter> matterList = new ArrayList<>();
            voList.forEach(d -> {
                ActMatter matter = new ActMatter();
                BeanUtils.copyProperties(act, matter);
                matter.setIsCheck(d.getIsSelect());
                matter.setActId(actId);
                matter.setDelFlag(0);
                matter.setVersion(1);
                matter.setCreateTime(DateUtils.formatTime(new Date()));
                matter.setUpdateTime(DateUtils.formatTime(new Date()));
                matter.setDictId(d.getId());
                matterList.add(matter);
            });
            int i = activityMapper.insert(activity);
            if (i > 0) {
                contentMapper.insert(content);
                boolean b = matterService.saveBatch(matterList);
                if (b) {
                    //缓存formId 七天自动过期
//                    redisUtil.set(actId, formId, 60 * 60 * 24 * 7);
                    result.setSuccess(true);
                    result.setResult(actId);
                    result.setMessage("活动创建成功");
                } else {
                    result.setSuccess(false);
                    result.setCode(1);
                    result.setMessage("活动创建失败");
                }
            } else {
                result.setCode(1);
                result.setSuccess(false);
                result.setMessage("活动创建失败");
            }
        }
        return result;
    }

    @Transactional
    @Override
    public Result editActivity(WxAct act, String actId) {
        Result result = new Result();
        QueryWrapper<ActUserRecord> wrapper = new QueryWrapper<>(new ActUserRecord());
        wrapper.eq("act_id", actId);
        Integer count = recordMapper.selectCount(wrapper);
        Activity activity = new Activity();
        BeanUtils.copyProperties(act, activity);
        activity.setId(actId);
        QueryWrapper<ActContent> contentQueryWrapper = new QueryWrapper<>(new ActContent());
        contentQueryWrapper.eq("act_id", actId);
        ActContent content = new ActContent();
        content.setContent(act.getContent());
        List<ActDictVo> voList = act.getDictVos();

        //去遍历传进来的事项id 看是否已经存在 存在则跳过新增
        if (count == 0) {
            //1. 还没有人报名的活动，活动相关信息可以全部修改
            QueryWrapper<ActMatter> queryWrapper = new QueryWrapper<>(new ActMatter());
            queryWrapper.eq("act_id", actId);
            matterService.remove(queryWrapper);
            //1.1修改活动相关属性
        }
        //1.2删去现有的活动事项，重新添加
        List<ActMatter> matterList = new ArrayList<>();
        voList.forEach(d -> {
            ActMatter matter1 = matterService.getById(d.getId());
            if (matter1 == null) {
                ActMatter matter = new ActMatter();
                BeanUtils.copyProperties(act, matter);
                matter.setIsCheck(d.getIsSelect());
                matter.setActId(actId);
                matter.setDelFlag(0);
                matter.setVersion(1);
                matter.setCreateTime(DateUtils.formatTime(new Date()));
                matter.setUpdateTime(DateUtils.formatTime(new Date()));
                matter.setDictId(d.getId());
                matterList.add(matter);
            }
        });
        int rows = activityMapper.updateById(activity);
        if (rows > 0) {
            //排除之前有的
            matterService.saveBatch(matterList);
            contentMapper.update(content, contentQueryWrapper);
            result.setSuccess(true);
            result.setMessage("修改成功");
        } else {
            result.setCode(1);
            result.setSuccess(false);
            result.setMessage("活动创建失败");
        }
        return result;
    }

    @Override
    public Result detail(String actId, String userId) {
        Result<Map<String, Object>> result = new Result<>();
        //活动详情
        Map<String, Object> actDetail = activityMapper.findDetailByActId(actId);
        QueryWrapper<ActUserRecord> wrapper = new QueryWrapper<>(new ActUserRecord());
        wrapper.eq("act_id", actId);
        wrapper.eq("user_id", userId);
        int rows = recordMapper.selectCount(wrapper);
        if (rows > 0) {
            actDetail.put("isEnroll", 1);
        } else {
            actDetail.put("isEnroll", 0);
        }

        result.setResult(actDetail);
        result.setSuccess(true);
        return result;
    }

    @Override
    public Result actUsers(String actId, Integer orderType) {
        Result<List<ActUserVo>> result = new Result<>();
        List<ActUserVo> list = activityMapper.findJoinActUserList(actId, orderType);
        List<ActUserVo> listVo = new ArrayList<>();
        list.forEach(vos -> {
            ActUserVo actUserVo = new ActUserVo();
            BeanUtils.copyProperties(vos, actUserVo);
            List<ActMatterValueVo> matterValues = matterService.findKV(vos.getUserId(), actId);
            matterValues.sort((o1, o2) -> {
                if (o1.getSort().equals(o2.getSort())) {
                    return o1.getParamName().hashCode() - o2.getParamName().hashCode();
                } else {
                    return o1.getSort() - o2.getSort();
                }
            });
            actUserVo.setMatterValueVos(matterValues);
            listVo.add(actUserVo);
        });
        result.setResult(listVo);
        result.setSuccess(true);
        return result;
    }

    @Override
    @Transactional
    public Result signUp(List<SignUp> signUps, String userId, String actId, String shareId, Integer type) {
        Result<String> result = new Result<>();

        //判断当前时间节点是否可以报名
        Activity a = activityMapper.selectByActId(actId);
        long endTime = Objects.requireNonNull(DateUtil.fomatDate1(a.getEndTime().replaceAll("/", "-"))).getTime();
        long startTime = Objects.requireNonNull(DateUtil.fomatDate1(a.getStartTime().replaceAll("/", "-"))).getTime();
        long localTime = new Date().getTime();
        if (endTime - localTime < 0 || startTime - localTime > 0) {
            result.setSuccess(false);
            result.setCode(1);
            result.setMessage("当前时间不能报名，无法报名");
        } else if (a.getStatus() == 3) {
            result.setSuccess(false);
            result.setCode(1);
            result.setMessage("活动已取消，无法报名");
        } else {
            QueryWrapper<ActUserRecord> wrapper = new QueryWrapper<>(new ActUserRecord());
            wrapper.eq("act_id", actId);
            wrapper.eq("user_id", userId);
            ActUserRecord hasRecord = recordMapper.selectOne(wrapper);
            //判断是否需要收费
            if (hasRecord == null) {
                ActUserRecord record = new ActUserRecord();
                record.setActId(actId);
                record.setUserId(userId);
                if (a.getIsNeedCheck().equals(1)) {
                    //判断是否需要审核 1否 直接报名通过
                    record.setStatus(2);
                } else {
                    //需要审核
                    record.setStatus(1);
                }
                record.setIsArrived(1);
                record.setCreateTime(new Date());
                record.setDelFlag(0);
                int row = recordMapper.insert(record);
                //如果是点击分享报名的 则传入分享id
                if (!StringUtils.isUndefined(shareId)) {
                    ActShare actShare = new ActShare();
                    actShare.setShareType(type);
                    actShare.setInviteId(userId);
                    actShare.setUserId(shareId);
                    actShare.setActId(actId);
                    actShare.setNum(0);
                    actShare.setReward(0.00);
                    shareMapper.insert(actShare);
                }
                if (row > 0) {
                    List<ActMatterValue> matterValues = new ArrayList<>();
                    signUps.forEach(s -> {
                        ActMatterValue value = new ActMatterValue();
                        BeanUtils.copyProperties(s, value);
                        value.setCreateTime(new Date());
                        value.setVersion(1);
                        value.setDelFlag(0);
                        value.setUserId(userId);
                        matterValues.add(value);

                    });
                    Activity activity = activityMapper.selectById(actId);
                    activity.setCurUser(activity.getCurUser() + 1);
                    activity.setVersion(activity.getVersion() + 1);
                    activityMapper.updateById(activity);
                    boolean b = valueService.saveBatch(matterValues);
                    if (b) {
                        if (a.getPay().compareTo(new BigDecimal(0)) > 0) {
                            ActPay actPay = new ActPay();
                            actPay.setUserId(userId);
                            actPay.setActId(actId);
                            actPay.setPay(a.getPay());
                            actPay.setPayType(1);
                            actPay.setStatus(0);
                            //生成订单号
                            String orderNo = OrderUtils.orderNo();
                            actPay.setOrderNo(orderNo);
                            boolean b1 = payService.save(actPay);
                            if (b1) {
                                result.setResult(orderNo);
                                result.setSuccess(true);
                                result.setMessage("报名成功");
                            } else {
                                result.setCode(1);
                                result.setMessage("报名失败");
                            }
                        } else {
                            result.setSuccess(true);
                            result.setMessage("报名成功");
                        }
                    } else {
                        result.setCode(1);
                        result.setMessage("报名失败");
                    }
                } else {
                    result.setCode(1);
                    result.setMessage("报名失败");
                }
            } else {
                result.setCode(1);
                result.setMessage("您已经报名了,无需在报名");
            }
        }
        return result;
    }


    @Override
    public Result verify(Verify verify) {
        Result result = new Result();
        //校验审核人是否未小程序管理员,校验是否是本人创建的活动，如果是则可以审核，如果不是则不能审核
        QueryWrapper<Activity> queryWrapper = new QueryWrapper<>(new Activity());
        queryWrapper.eq("user_id", verify.getUserId());
        queryWrapper.eq("id", verify.getActId());
        Activity hasAct = activityMapper.selectOne(queryWrapper);
        ActUser user = userMapper.selectById(verify.getUpdateBy());
        if (null == hasAct && !Const.ADMIN_TYPE.equals(user.getType())) {
            result.setSuccess(false);
            result.setCode(1);
            result.setMessage("您不是管理员,没有审核权限");
        } else {
            QueryWrapper<ActUserRecord> wrapper = new QueryWrapper<>(new ActUserRecord());
            wrapper.eq("act_id", verify.getActId());
            wrapper.eq("user_id", verify.getUserId());
            ActUserRecord record = recordMapper.selectOne(wrapper);
            if (record == null) {
                result.setSuccess(false);
                result.setCode(1);
                result.setMessage("未找到该用户的报名信息");
            } else if (record.getStatus().equals(verify.getStatus())) {
                result.setSuccess(false);
                result.setCode(1);
                result.setMessage("未作任何修改");
            } else {
                BeanUtils.copyProperties(verify, record);
                record.setStatus(verify.getStatus());
                record.setUpdateTime(new Date());
                record.setUpdateBy(verify.getUpdateBy());
                recordMapper.updateById(record);
                if (Const.UN_PASS.equals(verify.getStatus())) {
                    //未通过 活动当前通过人数减一
                    Activity activity = activityMapper.selectById(verify.getActId());
                    activity.setCurUser(activity.getCurUser() - 1);
                    activityMapper.updateById(activity);
                }
            }

        }

        return result;
    }

    @Override
    public IPage<ActivityVo> findByPage(IPage<ActivityVo> page, String userId) {
        return activityMapper.findByPage(page, userId);
    }

    @Override
    public Result goEditActivity(String actId) {
        Result<Map<String, Object>> result = new Result<>();
        Map<String, Object> map = new HashMap<>();
        Map<String, Object> activity = activityMapper.findDetailByActId(actId);
        //报名需要填写的信息
        List<ActDictVo> dictVos = dictMapper.findList();
        List<ActMatterVo> matterList = matterService.listByActId(actId);
        dictVos.forEach(dictVo -> {
            matterList.forEach(m -> {
                if (dictVo.getId().equals(m.getDictId())) {
                    dictVo.setCheck(true);
                }
            });
        });
        map.put("act", activity);
        map.put("dict", dictVos);
//        map.put("matterList",matterList);
        result.setSuccess(true);
        result.setResult(map);
        return result;
    }

    @Override
    public IPage<ActivityVo> myJoinRecord(String userId, IPage<ActivityVo> page) {
        return activityMapper.findmyJoinRecordByPage(page, userId);
    }

    @Override
    public Result saveOrUpdateFormId(String formId, String actId, String userId, String openId) {
        ActForm form = new ActForm();
        form.setActId(actId);
        form.setFormId(formId);
        form.setUserId(userId);
        form.setOpenId(openId);
        boolean b = formService.save(form);
        Result result = new Result();
        if (b) {
            return result;
        }
        result.setCode(1);
        return result;
    }

    @Override
    public IPage<ActivityVo> allActivities(Page<ActivityVo> page) {
        return activityMapper.allActivities(page);
    }
}
